package org.cms;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.cms.annotation.GoogleCalendar;
import org.cms.call.GetCalendarListCall;
import org.cms.call.GetEventsCall;
import org.cms.call.GetNewTokenCall;
import org.cms.dao.IDao;
import org.cms.entities.Event;
import org.cms.raw.calendar.EventRaw;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import javax.ejb.EJB;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

/**
 *
 *
 */
@GoogleCalendar
public class GoogleCalendarFacade implements ICalendarService<Event> {

    private static final String CLIENT_ID = "170966694283-mf1ovt38epobmj622gi20v0diq6i6bhv.apps.googleusercontent.com";
    private static final String CLIENT_SECRET = "uDDpNQziXRjWoN1-NfMmjNdQ";

    @EJB(beanName = "EventDao")
    IDao eventDao;

    Logger log = Logger.getLogger("GoogleCalendarFacade");

    private PropertiesHandler tokenProperties = new PropertiesHandler("calendar_tokens.properties");

    /**
     * Retrive a list of event for a specific user
     *
     * @return the list of Events
     * @throws IOException
     * @throws JSONException
     */
    @Override
    public List<Event> getUserCalendar() {


        HttpClient httpclient = HttpClients.createDefault();
        String refreshToken = "UNDEFINED";
        String access_token = "UNDEFINED";

        List<Event> eventList = new ArrayList<>();

        boolean refreshed = false;
        boolean changed = false;
        try {

            for (String key : tokenProperties.stringPropertyNames()) {
                refreshToken = key;
                access_token = tokenProperties.getProperty(key);

                GetCalendarListCall getCalendarListCall = new GetCalendarListCall(httpclient, access_token).invoke();
                // Refresh Token
                if (getCalendarListCall.getResponse().getStatusLine().getStatusCode() != 200) {

                    //consume the failed response
                    EntityUtils.consume(getCalendarListCall.getResponse().getEntity());
                    access_token = new GetNewTokenCall(httpclient, refreshToken, CLIENT_ID, CLIENT_SECRET).invoke().getNewAccessToken();
                    refreshed = true;
                    tokenProperties.setProperty(refreshToken, access_token);
                    changed = true;
                }
                if (refreshed) {
                    getCalendarListCall = new GetCalendarListCall(httpclient, access_token).invoke();
                }
                String output = getCalendarListCall.getResponseContentAsString();

                JSONObject json = new JSONObject(output);
                System.out.println(output);
                String calendarId = json.getJSONArray("items").getJSONObject(0).getString("id");

                GetEventsCall getEventsCall = new GetEventsCall(access_token, calendarId, httpclient).invoke();

                String eventsAsString = getEventsCall.getResponseContentAsString();
                JSONArray eventsJson = new JSONObject(eventsAsString).getJSONArray("items");

                Gson gson = new GsonBuilder().create();

                log.info("iterating over " + eventsJson.length() + " events");


                for (int i = 0; i < eventsJson.length(); i++) {
                    JSONObject jsonObject = eventsJson.getJSONObject(i);
                    EventRaw eventRaw = gson.fromJson(jsonObject.toString(), EventRaw.class);
                    Event event = EventMapper.map(eventRaw);
                    eventList.add(event);
                    log.info("EVENT captured : " + event.getId());

                }
            }
            if (changed) {
                tokenProperties.updateProperties();
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        } finally {
            // When HttpClient instance is no longer needed,
            // shut down the connection manager to ensure
            // immediate deallocation of all system resources
            httpclient.getConnectionManager().shutdown();
        }

        eventDao.mergeList(eventList);

        return eventList;

    }
}

